using System;
using System.Collections;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.IO;

using WPS.Libraries.CssDom;
using System.Collections.Generic;

namespace WPS.Modules.StyleLibrary
{
	/// <summary>
	/// Page for displaying an overview of all editable styles in the Style Library.
	/// </summary>
	public partial class Overview : System.Web.UI.Page
	{
		#region Template controls

		/// <summary>Output to list styles.</summary>
		protected string TableStylesList;
		/// <summary>Output to list styles.</summary>
		protected string ImageStylesList;
		/// <summary>Output to list styles.</summary>
		protected string HeadingStylesList;
		/// <summary>Output to list styles.</summary>
		protected string FontStylesList;
		/// <summary>Output to list styles.</summary>
		protected string TextBoxStylesList;

		/// <summary>Contains which styles are shown if not all. (e.g. "tables")</summary>
		protected string SelectedPanel = "headings";

		#endregion

		#region Private variables

		/// <summary>Lists of current class names from wysiwyg.css</summary>
		private StyleNameList ClassNames;

		#endregion

		#region Page events

		protected void Page_Load(object sender, System.EventArgs e)
		{
			// Authenticate user
			IStyleLibraryIntegration cms = new StyleLibraryIntegration();
			if(!cms.CheckAccess())
			{
				Response.Redirect(cms.GetLoginPage(), true);
			}
			
			if(!Page.IsPostBack)
			{
				// Hide all panels and show only one?
				if(!String.IsNullOrEmpty(Request.QueryString["styles"]))
				{
					string panel = Request.QueryString["styles"];
					if(panel == "headings" ||
						panel == "fonts" || 
						panel == "tables" || 
						panel == "images" || 
						panel == "textboxes")
					{
						this.SelectedPanel = Request.QueryString["styles"];
					}
				}
			}

			this.ClassNames = StyleSheetManager.LoadAllStyles(
				Server.MapPath(cms.GetEditableCssWebPath()));
			RenderPreviews();
		}

		protected void Page_PreRender(object sender, System.EventArgs e)
		{
			DataBind();
		}

		#endregion

		#region Create previews for each style library

		/// <summary>
		/// Render overview for each style library.
		/// </summary>
		private void RenderPreviews()
		{
			CreateTablePreviews();
			CreateImagePreviews();
			CreateHeadingPreviews();
			CreateFontPreviews();
			CreateTextBoxPreviews();
		}

		/// <summary>
		/// Render Heading previews.
		/// </summary>
		private void CreateHeadingPreviews()
		{
			string demoHtml = "<div class=\"preview\"><h{0}>Heading {0}</h{0}></div>";
			Hashtable popupLinks = new Hashtable();
			popupLinks["edit"] = "javascript:editHeading();";

			// Fake class names array, hardcoded 1-6.
			List<string> headingClassNames = new List<string>();
			for(int i = 1; i < 7; i++)
			{
				headingClassNames.Add(i.ToString());
			}

			this.HeadingStylesList = CreatePreviews(demoHtml, headingClassNames, "HeadingPopup", popupLinks, "Headings");
		}

		/// <summary>
		/// Render Font Style previews.
		/// </summary>
		private void CreateFontPreviews()
		{

			string demoHtml = "<div class=\"preview\"><span class=\"{0}\">Font style {0}</div></div>";

			Hashtable popupLinks = new Hashtable();
			popupLinks["edit"] = "javascript:editFont('edit', '{0}');";
			popupLinks["editasnew"] = "javascript:editFont('editasnew', '{0}');";
			popupLinks["delete"] = "javascript:deleteFont('{0}');";

			this.FontStylesList = CreatePreviews(demoHtml, this.ClassNames.Fonts, "FontPopup", popupLinks, "");
		}

		/// <summary>
		/// Render Table style previews.
		/// </summary>
		private void CreateTablePreviews()
		{
			string demoHtml =
				"<div class=\"preview\"><table class=\"{0}\">" +
				"<tr><th>a</th><th>b</th><th>c</th><th>d</th></tr>" +
				"<tr class=\"alt\"><th>a</th><td>b</td><td>c</td><td>d</td></tr>" +
				"<tr><td>a</td><td>b</td><td>c</td><td>d</td></tr>" +
				"<tr class=\"alt\"><th>a</th><td>b</td><td>c</td><td>d</td></tr>" +
				"</table></div>";

			Hashtable popupLinks = new Hashtable();
			popupLinks["use"] = "javascript:StyleLibraryOverviewDialog.useStyle('table', '{0}');";
			popupLinks["edit"] = "javascript:editTable('edit', '{0}');";
			popupLinks["editasnew"] = "javascript:editTable('editasnew', '{0}');";
			popupLinks["delete"] = "javascript:deleteTable('{0}');";

			this.TableStylesList = CreatePreviews(demoHtml, this.ClassNames.Tables, "TablePopup", popupLinks, "");
		}

		/// <summary>
		/// Render loaded Image Styles.
		/// </summary>
		private void CreateImagePreviews()
		{
			string demoHtml = "<div class=\"preview\"><img class=\"{0}\" src=\"img/StyleSheetImage.jpg\"/></div>";

			Hashtable popupLinks = new Hashtable();
			popupLinks["use"] = "javascript:StyleLibraryOverviewDialog.useStyle('img','{0}');";
			popupLinks["edit"] = "javascript:editImage('edit', '{0}');";
			popupLinks["editasnew"] = "javascript:editImage('editasnew', '{0}');";
			popupLinks["delete"] = "javascript:deleteImage('{0}');";

			this.ImageStylesList = CreatePreviews(demoHtml, this.ClassNames.Images, "ImagePopup", popupLinks, "");
		}

		/// <summary>
		/// Render loaded Text Box Styles.
		/// </summary>
		private void CreateTextBoxPreviews()
		{
			string demoHtml = "<div class=\"preview\"><div class=\"{0}\"><h2>{0}</h2><p>Text box</p></div></div>";

			Hashtable popupLinks = new Hashtable();
			popupLinks["use"] = "javascript:StyleLibraryOverviewDialog.useStyle('div','{0}');";
			popupLinks["edit"] = "javascript:editTextBox('edit', '{0}');";
			popupLinks["editasnew"] = "javascript:editTextBox('editasnew', '{0}');";
			popupLinks["delete"] = "javascript:deleteTextBox('{0}');";

			this.TextBoxStylesList = CreatePreviews(demoHtml, this.ClassNames.TextBoxes, "TextBoxPopup", popupLinks, "");
		}

		#endregion

		#region General preview creation functions

		// See doc below, same but one demoHtml for all styles.
		private string CreatePreviews(string demoHtml, List<string> classNames, string popupName, Hashtable popupLinks, string singlePopup)
		{
			string[] demos = new string[classNames.Count];
			for(int i = 0; i < classNames.Count; i++)
			{
				demos[i] = demoHtml;
			}
			return CreatePreviews(demos, classNames, popupName, popupLinks, singlePopup);
		}

		/// <summary>
		/// Create preview and populate the preview list with data.
		/// </summary>
		/// <param name="demoHtml">Strings for the demo previews. {0} replaced to styleName. (as many as classes!)</param>
		/// <param name="classNames">Name of css classes to generate.</param>
		/// <param name="popupName">Name of popup menu in DM.</param>
		/// <param name="popupLinks">Hash of popup links. Keys: "edit", "editasnew", "delete". To omit a menu, omit the key.</param>
		/// <param name="singlePopup">Create a single popup menu for all items with this name. Leave empty to create menu for each item.</param>
		/// <returns>Hashtable, 2 items: ["js"]: array for javascript, ["dm"] rendered preview table html.</returns>
		private string CreatePreviews(string[] demoHtml, List<string> classNames, string popupName, Hashtable popupLinks, string singlePopup)
		{
			StringBuilder preview = new StringBuilder();
			preview.AppendFormat("<table style=\"width: 100%\">");

			string actions = CreatePreviewActions(popupName, popupLinks);
			string commonPreview = "";
			bool haveStyles = false;

			for(int i = 0; i < classNames.Count; i++)
			{
				// Speparate dm entries for each style
				if(singlePopup == "")
				{
					preview.AppendFormat(
						(haveStyles ? "<tr><td>{0}</td><td><strong>{1}</strong><br/>{2}</td></tr>" : "<tr><td style=\"width: 33%\">{0}</td><td><strong>{1}</strong><br/>{2}</td></tr>"),
						string.Format(demoHtml[i], classNames[i]),
						classNames[i],
						actions.Replace("{0}", (string)classNames[i]));
					haveStyles = true;
				}
				else
				{
					commonPreview += string.Format(demoHtml[i], (string)classNames[i]);
				}
			}

			// Make a single line for all items.
			if(singlePopup != "")
			{
				preview.AppendFormat("<tr><td style=\"width: 33%\">{0}</td><td><strong>{1}</strong><br/>{2}</td></tr>",
						commonPreview,
						singlePopup,
						actions.Replace("{0}", singlePopup));
				haveStyles = true;
			}

			preview.AppendLine("</table>");

			if(haveStyles)
			{
				return preview.ToString();
			}
			else
			{
				return "{#stylelibrary_dlg.no_styles_yet}";
			}
		}

		/// <summary>
		/// Creates preview menu.
		/// </summary>
		/// <returns></returns>
		private string CreatePreviewActions(string popupName, Hashtable popupLinks)
		{
			StringBuilder actions = new StringBuilder();

			if(popupLinks["use"] != null)
			{
				actions.AppendFormat("<a href=\"{0}\">{1}</a>\r\n", popupLinks["use"], "{#stylelibrary_dlg.use_style}");
			}
			if(popupLinks["edit"] != null)
			{
				if(actions.Length > 0) { actions.Append(" | "); }
				actions.AppendFormat("<a href=\"{0}\">{1}</a>\r\n", popupLinks["edit"], "{#stylelibrary_dlg.edit}");
			}
			if(popupLinks["editasnew"] != null)
			{
				if(actions.Length > 0) { actions.Append(" | "); }
				actions.AppendFormat("<a href=\"{0}\">{1}</a>\r\n", popupLinks["editasnew"], "{#stylelibrary_dlg.edit_as_new}");
			}
			if(popupLinks["delete"] != null)
			{
				if(actions.Length > 0) { actions.Append(" | "); }
				actions.AppendFormat("<a href=\"{0}\">{1}</a>\r\n", popupLinks["delete"], "{#stylelibrary_dlg.style_delete}");
			}

			return actions.ToString();
		}

		#endregion

		/// <summary>
		/// Escape the " to &quot; for use in HTML attributes.
		/// </summary>
		/// <param name="str">String to escape.</param>
		/// <returns>All " replaced to &quot;.</returns>
		public string quot(string str)
		{
			return str.Replace("\"", "&quot;");
		}

		/// <summary>
		/// Escape the ' to \' for use in javascript variables;
		/// </summary>
		/// <param name="str">String to escape.</param>
		/// <returns>All ' replaced to \'.</returns>
		public string esc(string str)
		{
			return str.Replace("'", "\\'");
		}


	}
}
